function getVertexBuffer(vertexData) {
  const vertexCount = vertexData.length / 12
  const noise = 0.03
  for (let i = 0; i < vertexCount; i++) {
    const vertexIndex = i * 12
    // x
    vertexData[vertexIndex] = vertexData[vertexIndex] + Math.random() * noise - noise / 2
    // y
    vertexData[vertexIndex + 1] = vertexData[vertexIndex + 1] + Math.random() * noise - noise / 2
    // z
    vertexData[vertexIndex + 2] = vertexData[vertexIndex + 2] + Math.random() * noise - noise / 2
    // normal x
    // vertexData[vertexIndex + 3]
    // normal y
    // vertexData[vertexIndex + 4]
    // normal z
    // vertexData[vertexIndex + 5]
    // u
    // vertexData[vertexIndex + 6]
    // v
    // vertexData[vertexIndex + 7]
    // r
    vertexData[vertexIndex + 8] = i / vertexCount
    // g
    vertexData[vertexIndex + 9] = i / vertexCount
    // b
    vertexData[vertexIndex + 10] = i / vertexCount
    // a
    // vertexData[vertexIndex + 11]
  }
  return new Float32Array(vertexData)
}

function buildSphere(
  vertexs,
  indices,
  radius = 1,
  widthSegments = 32,
  heightSegments = 16,
  phiStart = Math.PI / 2,
  phiLength = Math.PI * 2,
  thetaStart = Math.PI,
  thetaLength = Math.PI
) {
  widthSegments = Math.max(3, Math.floor(widthSegments))
  heightSegments = Math.max(2, Math.floor(heightSegments))

  const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI)

  let index = 0
  const grid = []

  // generate vertices, normals and uvs
  for (let iy = 0; iy <= heightSegments; iy++) {
    const verticesRow = []
    const v = iy / heightSegments
    // special case for the poles
    let uOffset = 0
    if (iy == 0 && thetaStart == 0) {
      uOffset = 0.5 / widthSegments
    } else if (iy == heightSegments && thetaEnd == Math.PI) {
      uOffset = -0.5 / widthSegments
    }
    for (let ix = 0; ix <= widthSegments; ix++) {
      const u = ix / widthSegments
      // vertex
      const vertexX = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength)
      const vertexY = radius * Math.cos(thetaStart + v * thetaLength)
      const vertexZ = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength)
      vertexs.push(vertexX, vertexY, vertexZ)
      // normal
      vertexs.push(vertexX / 3, vertexY / 3, vertexZ / 3)
      // uv
      vertexs.push(u + uOffset, 1 - v)
      // color
      vertexs.push(0, 0, 0, 1)

      verticesRow.push(index++)
    }
    grid.push(verticesRow)
  }
  // indices
  for (let iy = 0; iy < heightSegments; iy++) {
    for (let ix = 0; ix < widthSegments; ix++) {
      const a = grid[iy][ix + 1]
      const b = grid[iy][ix]
      const c = grid[iy + 1][ix]
      const d = grid[iy + 1][ix + 1]

      if (iy !== 0 || thetaStart > 0) indices.push(a, d, b)
      if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, d, c)
    }
  }
}

Component({
  behaviors: [require('../../common/share-behavior').default],
  properties: {
    a: Number,
  },
  data: {
    loaded: false
  },
  lifetimes: {},
  methods: {
    handleReady({ detail }) {
      const xrScene = this.scene = detail.value
      console.log('xr-scene', xrScene)
      const xrFrameSystem = wx.getXrFrameSystem()

      this.geometryRoot = this.scene.getElementById('geometryRoot')

      const geoRadius = 1

      this.vertexData = []
      this.indexData = []
      // 构造圆形的 顶点信息，可以通过增加切分区域增加顶点数量
      // 一般复杂人物 vertex 长度 77030 index 88266
      buildSphere(this.vertexData, this.indexData, geoRadius, 64, 64)

      console.log('vertexDataCount', this.vertexData.length)
      console.log('indexDataCount', this.indexData.length)

      // 注册 Geometry 信息
      xrFrameSystem.registerGeometry('man', scene => {
        const vl = scene.createVertexLayout({
          attributes: [
            {
              name: 'a_position',
              format: xrFrameSystem.EVertexFormat.FLOAT3,
              offset: 0,
            },
            {
              name: 'a_normal',
              format: xrFrameSystem.EVertexFormat.FLOAT3,
              offset: 12,
            },
            {
              name: 'a_texCoord',
              format: xrFrameSystem.EVertexFormat.FLOAT2,
              offset: 24,
            },
            {
              name: 'a_color',
              format: xrFrameSystem.EVertexFormat.FLOAT4,
              offset: 32,
            }
          ],
          stride: 48
        })

        // VertexBuffer IndexBuffer 不能动态更改长度，需要一开始设定较大的长度。
        const vb = new Float32Array(this.vertexData.length)
        const ib = new Uint16Array(this.indexData)

        const geo = scene.createGeometry(vl, vb, ib)

        geo.setBoundBall(new xrFrameSystem.Vector3(), 1)
        geo.addSubMesh(ib.length, 0, 0)

        return geo
      })

      this.geoElem = xrScene.createElement(xrFrameSystem.XRMesh, {
        geometry: 'man',
        material: 'simple-mat',
        position: '0 0 0'
      })
      this.geometryRoot.addChild(this.geoElem)

      // 延时保证挂载与初始化完毕
      setTimeout(() => {
        this.meshGeo = this.geoElem.getComponent(xrFrameSystem.Mesh)
        this.geometryGeo = this.meshGeo.geometry

        this.matGeo = this.meshGeo.material
        // 使用顶点色
        this.matGeo.setMacro('WX_USE_COLOR_0', true)
        // 设定 绘制双面
        this.matGeo.setRenderState('cullOn', false)

        xrScene.event.add('tick', this.handleTick.bind(this))
      }, 100)
    },

    handleAssetsProgress({ detail }) {
      console.log('assets progress', detail.value)
    },
    handleAssetsLoaded({ detail }) {
      console.log('assets loaded', detail.value)
    },
    handleTick(delta) {
      const vb = getVertexBuffer(this.vertexData)
      const ib = new Uint16Array(this.indexData)

      this.geometryGeo.uploadVertexBuffer(0, vb)
      this.geometryGeo.uploadIndexBuffer(0, ib)
    },

  }
})
